package com.itheima.tlias84.aspect;

import com.alibaba.fastjson2.JSONObject;
import com.itheima.tlias84.entity.Emp;
import com.itheima.tlias84.entity.OperateLog;
import com.itheima.tlias84.mapper.EmpMapper;
import com.itheima.tlias84.mapper.LogMapper;
import com.itheima.tlias84.utils.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;

/**
 * 日志切面
 *
 */

/**
 * @Aspect 标识为切面类
 * @Component 让Spring管理，自动注入
 */
@Slf4j
@Aspect//标识为切面类
@Component
public class LogAspect {
    @Resource
    HttpServletRequest request;
    @Resource
    LogMapper logMapper;
    @Resource
    EmpMapper empMapper;


    @Around("@annotation(com.itheima.tlias84.annotation.Log)")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取token，解析
        String token = request.getHeader("token");
        JSONObject object = JwtUtil.verifyToken(token);
        //操作人姓名
        String operateEmpName = object.getString("username");
        //操作人id
//        Integer operateEmpId = object.getInteger("id");
        Emp emp = empMapper.selectEmpByUsername(operateEmpName);
        Integer operateEmpId = emp.getId();
        //操作时间：获取当前时间
        LocalDateTime operateTime = LocalDateTime.now();
        //操作类名
        String className = joinPoint.getTarget().getClass().getName();
        //操作方法名
        String methodName = joinPoint.getSignature().getName();
        //操作方法参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);
        //执行耗时-原方法执行前
        long start = System.currentTimeMillis();
        //执行父类方法
        Object proceed =joinPoint.proceed();
        //执行耗时-原方法执行后
        long end = System.currentTimeMillis()-start;
        //操作方法返回值
        String returnValue = JSONObject.toJSONString(proceed);
        //操作执行耗时
        Long costTime = end;

        //新建实体类并赋值
        OperateLog operateLog = new OperateLog(null, operateEmpId, operateTime, className,
                methodName, methodParams, returnValue, costTime, operateEmpName);
        //调用mapper插入数据
        logMapper.insertLog(operateLog);
        log.info("AOP记录操作日志：{}", operateLog);
        return proceed;

    }



//    最初写法：运行时直接报错
    //        try {
////            long start = System.currentTimeMillis();
//            //1、执行父类方法
////            Object proceed = joinPoint.proceed();
//            //2、插入日志-->注解写逻辑
//            log.info("操作{}方法，插入日志", joinPoint.getSignature().getName());
//            //获取数据-->set数据到实体类-->调用mapper，传入参数插入数据
//            OperateLog insertLogEntity = new OperateLog();
//            //操作时间1
//            insertLogEntity.setOperateTime(LocalDateTime.now());
//            //操作人姓名2
//
//            if (Objects.nonNull(token)) {
//                //解析token
////                JSONObject object = JwtUtil.verifyToken(token);
//                String username = object.getString("username");
//                insertLogEntity.setOperateEmpName(username);
//                //操作人id-3
//                Emp emp = empMapper.selectEmpByUsername(username);
//                insertLogEntity.setOperateEmpId(emp.getId());
//            }
//            //方法请求参数4
////            Object[] args = joinPoint.getArgs();
//            insertLogEntity.setMethodParams(Arrays.toString(args));
//            //类名5
////            Object target = joinPoint.getTarget();
////            insertLogEntity.setClassName(target.getClass().getName());
//            //方法名6
////            insertLogEntity.setMethodName(joinPoint.getSignature().getName());
//            //返回值7
//            insertLogEntity.setReturnValue(proceed.toString());
//            //执行耗时8
////            long l = System.currentTimeMillis() - start;
////            String s = String.valueOf(l);
////            Integer time = Integer.valueOf(s);
////            insertLogEntity.setCostTime(time);
//            logMapper.insertLog(insertLogEntity);
//            //3、@Around(@annotation(写注解的全路径))
//
//
//            return proceed;
//        } catch (Throwable e) {
//            throw new RuntimeException(e);
//        }











}
